package com.itbaizhan;

import java.sql.Connection;
import java.sql.PreparedStatement;

/*事务简介
事务：
事务是指作为单个逻辑工作单元执行的一系列操作,
要么完全地执行，要么完全地不执行。

事务操作流程：
开启事务
提交事务
回滚事务

JDBC中事务处理特点
在JDBC中，使用Connection对象来管理事务，默认为自动提交事务。
可以通过setAutoCommit(boolean autoCommit)方法设置事务是否自动提交，
参数为boolean类型，默认值为true，表示自动提交事务，
如果值为false则表示不自动提交事务，
需要通过commit方法手动提交事务或者通过rollback方法回滚事务。*/

//当用到DML语句时都要用到事务
public class AddBatchTest01 {
    //适合小量数据一起添加
    public void addBatch01(){
        Connection connection = null;
        PreparedStatement ps = null;
        try{
            connection = JdbcUtils.getConnection();
            ps = connection.prepareStatement("insert into users values(default,?,?)");
            //绑定数据
            for(int i=0;i<=1000;i++){
                ps.setString(1,"it"+i);
                ps.setInt(2,20);
                //缓存sQL语句
                ps.addBatch();
            }
            //执行所有缓存的sql语句
            ps.executeBatch();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JdbcUtils.closeResource(ps,connection);
        }

    }

    //批量处理数据
    //支持事务处理
    public void addBatch02(){
        Connection connection = null;
        PreparedStatement ps = null;
        try{
            connection = JdbcUtils.getConnection();
            //事务提交是默认是自动的(true)，现改为手动(false)
            connection.setAutoCommit(false);
            ps = connection.prepareStatement("insert users values(default,?,?)");
            for(int i=1;i<=1000;i++){
                ps.setString(1,"is"+i);
                ps.setInt(2,22);
                //缓存sQL语句
                ps.addBatch();
                //如果缓存数据有500条，执行SQL语句
                if(i%500 == 0){
                    ps.executeBatch();
                    //执行SQL语句后，清除缓存，为下一次做准备
                    ps.clearBatch();
                }
                //如果当500条数据后，出现错误 但前面500条都提交了
                //不符合事务要求：要么完全地执行，要么完全地不执行。
                //所以要手动提交，当出现异常时，回滚事务
                /*例：空指针异常*/
                if(i == 501){
                    String str = null;
                    str.length();
                }
            }
            //提交事务   SQL语句执行后再提交
            //connection.commit();
            //调用工具类也可以
            JdbcUtils.commit(connection);
        }catch (Exception e){
            e.printStackTrace();
            //有异常时，事务回滚
           // connection.rollback(); 这有异常处理，所以调用JDBC工具类更简洁
            JdbcUtils.rollback(connection);
        }finally {
            JdbcUtils.closeResource(ps,connection);
        }
    }

    public static void main(String[] args) {
        AddBatchTest01 ab = new AddBatchTest01();
       // ab.addBatch01();
        ab.addBatch02();
    }
}